#include "../header.h"

//公共数据。共享数据。
static int num = 1000;  // 1010

//条件
static int flg = 1 ;

//条件变量数据结构。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//双线程 对公共数据竞争，无序的。
//新的数据结构，互斥锁 + 条件变量 + 信号量。
//实现一个目标：在某个线程处理公共数据的时候，排斥其他任务。独占公共数据。直到释放公共数据。
//线程1 
//生产者线程。

//flg == 0 : 线程1 运行 线程2阻塞。
void * pthread_fun1(void * arg)
{
    if(flg)
      pthread_cond_wait(&cond,&mutex);   

    int num1 = 10 ;
    while(num1--)
    {
        //每秒钟操作屏幕文件。
        printf("this is %s test :%d :%lu,%d\n",__func__,getpid(),pthread_self(),++num);
        sleep(1);
    }
    flg == 1;
    pthread_cond_signal(&cond);

    //线程退出函数  返回2号状态。
    pthread_exit((void*)2);
}
//flg == 1 : 线程1 阻塞 线程2 运行。
//线程2 
//消费者线程。
void * pthread_fun2(void * arg)
{   
    if(!flg)
      pthread_cond_wait(&cond,&mutex);  

    int num1 = 10;
    while(num1--)
    {
        printf("this is %s test :%d :%lu %d\n",__func__,getpid(),pthread_self(),--num);
        sleep(1);
    }
    flg = 0 ;
    //唤醒。
    pthread_cond_signal(&cond);
    //返回5号状态。
    pthread_exit((void*)5);
}

int main(int argc, char const *argv[])
{

    //初始化
    if(pthread_cond_init(&cond,NULL))
    {
        perror("条件变量初始化失败!\n");
        return -1;
    }
    if(pthread_mutex_init(&mutex,NULL))
    {
        perror("互斥锁初始化失败!\n");
        return -1;
    }
    printf("条件变量与互斥锁 初始化成功!\n");


    pthread_t tid1 = 0 ,tid2 = 0 ;
    pthread_create(&tid1,NULL,pthread_fun1,NULL);
    pthread_create(&tid2,NULL,pthread_fun2,NULL);
    //阻塞本线程,等待目标线程执行完。

    //可以接收子线程的退出状态
    void * ret1 = NULL;
    void *ret2 = NULL;
    pthread_join(tid1,&ret1);
    pthread_join(tid2,&ret2);
    printf("pthread fun1 exit status:%lu\n",(long unsigned int)ret1);
    printf("pthread fun2 exit status:%lu\n",(long unsigned int)ret2);

    printf("main over\n");
    return 0;
}
